package com.xiaoke.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaoke.domain.ResponseResult;
import com.xiaoke.domain.dto.GetArticleListDTO;
import com.xiaoke.domain.entity.Article;
import com.xiaoke.domain.vo.*;
import com.xiaoke.exception.QueryException;
import com.xiaoke.mapper.ArticleMapper;
import com.xiaoke.service.ArticleService;
import com.xiaoke.service.CategoryService;
import com.xiaoke.service.TagMiddleService;
import com.xiaoke.utils.BeanCopyUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.xiaoke.constants.SystemConstants.ARTICLE_HOT_SIZE;
import static com.xiaoke.constants.SystemConstants.STATUS_NORMAL;
import static com.xiaoke.enums.TagTargetEnum.ARTICLE;

/**
 * 文章表(Article)表服务实现类
 *
 * @author xiaoke
 * @since 2023-03-16 22:23:53
 */
@Service("articleService")
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {

    @Resource
    CategoryService categoryService;

    @Lazy
    @Resource
    TagMiddleService tagMiddleService;


    @Override
    public ResponseResult hostArticle() {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper
                .eq(Article::getStatus,STATUS_NORMAL)
                .orderByDesc(Article::getBrowse);

        Page<Article> articlePage = new Page<>(1,ARTICLE_HOT_SIZE);

        page(articlePage,queryWrapper);

        List<Article> articleList = articlePage.getRecords();

        List<HostArticleVo> hostArticleVos = BeanCopyUtils.copyBeanList(articleList, HostArticleVo.class);

        return ResponseResult.okResult(hostArticleVos);
    }

    @Override
    public ResponseResult getArticleList(GetArticleListDTO getArticleListDTO) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(Article::getStatus,STATUS_NORMAL)
                .orderByDesc(Article::getIsTop)
                .orderByDesc(Article::getId)
                .eq(getArticleListDTO.getCategoryid() != null,Article::getCategoryid,getArticleListDTO.getCategoryid());

        Page<Article> articlePage = new Page<>(getArticleListDTO.getPageNum(),getArticleListDTO.getPageSize());

        page(articlePage,queryWrapper);

        List<Article> articleList = articlePage.getRecords();
        // 设置标签列表
        setArticleListTagList(articleList);
        // 设置分类名称
        setArticleListCategoryName(articleList);

        List<GetArticleListVo> getArticleListVos = BeanCopyUtils.copyBeanList(articleList, GetArticleListVo.class);

        PageVo pageVo = new PageVo(getArticleListVos,articlePage.getTotal());

        return ResponseResult.okResult(pageVo);
    }

    @Override
    public void setArticleListCategoryName(List<Article> list) {
        list.stream()
                .peek((Article article)-> article.setCategoryName(categoryService.getById(article.getCategoryid()).getName()))
                .collect(Collectors.toList());
    }

    @Override
    public void setArticleListTagList(List<Article> list) {
        list.stream()
                .peek((Article article)-> {
                    List<TagVo> tagVos  =  tagMiddleService.getByIdTagList(article.getId(),ARTICLE);
                    article.setTagList(tagVos);
                })
                .collect(Collectors.toList());
    }

    @Override
    public ResponseResult getByTagIdArticleList(Long id) {
        Set<Long> byIdsTargetIds = tagMiddleService.getByIdsTargetIds(id, ARTICLE);
        List<ConditionalQueryArticleVo> conditionalQueryArticleVos = conditionalQueryArticleVoBeanCopy(getByIdsArticleList(byIdsTargetIds));
        return ResponseResult.okResult(conditionalQueryArticleVos);
    }

    @Override
    public ResponseResult getByCategoryIdArticleList(Long id) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(Article::getStatus,STATUS_NORMAL)
                .eq(Article::getCategoryid,id);

        List<ConditionalQueryArticleVo> conditionalQueryArticleVos = conditionalQueryArticleVoBeanCopy(list(queryWrapper));
        return ResponseResult.okResult(conditionalQueryArticleVos);
    }

    @Override
    public ResponseResult getByValueArticleList(String value) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(Article::getStatus,STATUS_NORMAL)
                .like(Article::getContent,value);

        List<ConditionalQueryArticleVo> conditionalQueryArticleVos = conditionalQueryArticleVoBeanCopy(list(queryWrapper));
        return ResponseResult.okResult(conditionalQueryArticleVos);
    }

    @Override
    public List<Article> getByIdsArticleList(Set<Long> ids) {
        List<Article> articleList = new ArrayList<>();
        ids.stream()
                .peek(id-> {
                    LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper
                            .eq(Article::getStatus,STATUS_NORMAL)
                            .eq(Article::getId,id);
                    articleList.add(getOne(queryWrapper));
                })
                .collect(Collectors.toList());

        return articleList;
    }

    @Override
    public List<ConditionalQueryArticleVo> conditionalQueryArticleVoBeanCopy(List<Article> articleList) {
        return BeanCopyUtils.copyBeanList(articleList, ConditionalQueryArticleVo.class);
    }

    @Override
    public ResponseResult getArticle(String id) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(Article::getStatus,STATUS_NORMAL)
                .eq(Article::getId,id);

        Article article = findArticle(queryWrapper);

        GetArticleVo getArticleVo = BeanCopyUtils.copyBean(article, GetArticleVo.class);

        return  ResponseResult.okResult(getArticleVo);
    }

    @Override
    public Article findArticle(LambdaQueryWrapper<Article> queryWrapper) {
        Article article = getOne(queryWrapper);

        if(article == null) {
            throw  new QueryException();
        }

        article.setCategoryName(categoryService.getById(article.getCategoryid()).getName());

        List<TagVo> tagVos  =  tagMiddleService.getByIdTagList(article.getId(),ARTICLE);
        article.setTagList(tagVos);

        return  article;
    }

}

